package com.example.myapplication.ui.face;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.OrientationEventListener;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.annotation.NonNull;

import com.example.myapplication.R;
import com.example.myapplication.tools.StringUtils;
import com.journeyapps.barcodescanner.ViewfinderView;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.List;

/**
 * @author gy.lin
 * @create 2018/8/13
 * @Describe
 */

public class IdentifyFromCamera extends Activity {
    private SurfaceView mSurfaceView;
    private Button mTemplateButton;
    private Button mIdentifyButton;
    private TextView mStatusTextView;

    private Camera mCamera;
    private SurfaceHolder mSurfaceHolder;
//    private final int CAMERA_WIDTH = 640;
//    private final int CAMERA_HEIGH = 480;
    private final int CAMERA_WIDTH = 480;
    private final int CAMERA_HEIGH = 640;
    private final int cameraId = 0;

    private boolean ADD_OPTION = false;
    private boolean IDENTIFY_OPTION = false;

    private byte[] mTemplate1 = null;
    private byte[] mTemplate2 = null;


    private byte[] SecondTemplate = null;
    private ImageView mFirstImage;

    private int FACEID = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_identify_from_camera);
        initView();
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        super.onWindowFocusChanged(hasFocus);
        int screenWidth = getWindowManager().getDefaultDisplay().getWidth();
        int screenHeight = getWindowManager().getDefaultDisplay().getHeight();
        Log.e("======>>> ",  "width: "+ screenWidth  +  "   height: "+ screenHeight);
    }

    private void initView() {
        mSurfaceView = (SurfaceView)findViewById(R.id.identifySurfaceView);
        mTemplateButton = (Button)findViewById(R.id.AddtemplateButtonCamera);
        mIdentifyButton = (Button)findViewById(R.id.identifyButtonCamera);
        mStatusTextView = (TextView)findViewById(R.id.statusTextViewCamera);

        mSurfaceHolder = mSurfaceView.getHolder();
        mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                if(mCamera!=null){
//                    orientationListener.enable();
                    SetAndStartPreview(holder);
                }
            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

            }

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                if (mCamera != null) {
//                    orientationListener.disable();
                    mCamera.setPreviewCallback(null);
                    mCamera.stopPreview();
                    mCamera.release();
                    mCamera = null;
                }
            }
        });

        OpenCameraAndSetSurfaceviewSize(cameraId);

        mTemplateButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                ADD_OPTION = true;
            }
        });

        mIdentifyButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                IDENTIFY_OPTION = true;
            }
        });
        Button btn = findViewById(R.id.AddtemplateButtonCamera2);
        btn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                byFile();
            }
        });
        mFirstImage = (ImageView)findViewById(R.id.identifyFirstImage);
    }

    private Point mPreviewResolution;
    private void OpenCameraAndSetSurfaceviewSize(int cameraId) {

        if(mCamera == null){
            mCamera = Camera.open(cameraId);
        }
        int temp = 180;
        temp = getDegrees();
        mCamera.setDisplayOrientation(temp);

        Camera.Parameters parameters = mCamera.getParameters();
        Point point = new Point();

        point.x = 2592;
        point.y = 1944;
        this.mPreviewResolution = getPreviewResolution(parameters, point);
        parameters.setPreviewSize( mPreviewResolution.x,mPreviewResolution.y);
//        parameters.setPreviewSize( CAMERA_HEIGH,CAMERA_WIDTH);
        Camera.CameraInfo info = new Camera.CameraInfo();
        Camera.getCameraInfo(cameraId, info);
//        mCamera.setDisplayOrientation(90);
        mCamera.setParameters(parameters);
    }
    private Void SetAndStartPreview(SurfaceHolder holder) {
        try {
            int temp = 180;
            temp = getDegrees();
            mCamera.setDisplayOrientation(temp);

            mCamera.setPreviewDisplay(holder);

            Camera.Parameters parameters = mCamera.getParameters();
            parameters.setPreviewFormat(ImageFormat.NV21);
            parameters.setPreviewSize( mPreviewResolution.x,mPreviewResolution.y);
            mCamera.setPreviewCallback(new IdentifyPreview());
            mCamera.startPreview();
//            mCamera.setDisplayOrientation(90);
            //mCamera.cancelAutoFocus();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return null;
    }

    private int getDegrees(){
        android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo (cameraId , info);
        int rotation = getWindowManager ().getDefaultDisplay ().getRotation ();
        int degrees = 0;
        switch (rotation) {
            case Surface.ROTATION_0:
                degrees = 0;
                break;
            case Surface.ROTATION_90:
                degrees = 90;
                break;
            case Surface.ROTATION_180:
                degrees = 180;
                break;
            case Surface.ROTATION_270:
                degrees = 270;
                break;
        }
        int result;
        if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360;   // compensate the mirror
        } else {
            // back-facing
            result = ( info.orientation - degrees + 360) % 360;
        }
        return result;
    }

    private static Point getPreviewResolution(Camera.Parameters paramParameters, Point paramPoint)
    {
        Point localPoint = findBestPreviewSizeValue(paramParameters.getSupportedPreviewSizes(), paramPoint);
        paramPoint = localPoint;
        if (localPoint == null) {
            paramPoint = new Point(paramPoint.x >> 3 << 3, paramPoint.y >> 3 << 3);
        }
        return paramPoint;
    }

    private static Point findBestPreviewSizeValue(List<Camera.Size> paramList, Point paramPoint)
    {
//        paramList = paramList.iterator();
        int i = 0;
        int k = Integer.MAX_VALUE;
        int j = 0;
        int m = 0;
        int n = 0;
        for(Camera.Size localSize : paramList){
            m = localSize.width;
            n = localSize.height;
            int i1 = Math.abs(m - paramPoint.x) + Math.abs(n - paramPoint.y);
            if (i1 == 0) {
                break;
            }
            if (i1 < k) {
                j = n;
                i = m;
                k = i1;
            }
            m = i;
            n = j;
        }
        if ((m > 0) && (n > 0)) {
            return new Point(m, n);
        }
        return null;
    }

    private Void kill_camera() {
        if (mCamera != null) {
            mCamera.setPreviewCallback(null);
            mCamera.stopPreview();
            mCamera.release();
            mCamera = null;
        }
        return null;
    }

    class IdentifyPreview implements Camera.PreviewCallback{


        @Override
        public void onPreviewFrame(byte[] data, Camera camera) {
//            Log.e("------>>", "onPreviewFrame: ");
            // TODO Auto-generated method stub
            if(ADD_OPTION){
                ADD_OPTION = false;
                mTemplate1 = ZKLiveFaceManager.getInstance().getTemplateFromNV21(data,mPreviewResolution.x,mPreviewResolution.y);
                if(mTemplate1 == null){
                    mStatusTextView.setText(getString(R.string.extract_template_fail));
                    return;
                }
                if(ZKLiveFaceManager.getInstance().dbAdd("faceID_"+FACEID,mTemplate1)){
                    mStatusTextView.setText(""+getString(R.string.dbadd_template_success)+",id="+"faceID_"+FACEID);
                    FACEID ++;
                }else{
                    mStatusTextView.setText(getString(R.string.dbadd_template_fail));
                }
            }
            if(IDENTIFY_OPTION){
                IDENTIFY_OPTION = false;
                //Bitmap bitmap =BitmapFactory.decodeByteArray(data,0,data.length);//将byte[]数组转换为BItMap对象

                Bitmap bitmap = runInPreviewFrame(data,camera);
//                if(bitmap != null){
////                    mFirstImage.setImageBitmap(bitmap);
////                    tetet = bitmap;
////                    handler.sendEmptyMessage(0);
//                }else{
//                    mStatusTextView.setText("bitmap 为 null");
//                }
//
                mFirstImage.setImageBitmap(bitmap);
//                byte[] tttt = changeBitmapToBytes(bitmap);
                mTemplate2 = ZKLiveFaceManager.getInstance().getTemplateFromNV21(data,mPreviewResolution.x,mPreviewResolution.y);
                if(mTemplate2 == null){
                    mStatusTextView.setText(getString(R.string.extract_template_fail) + "111");
                    return;
                }
                String id = ZKLiveFaceManager.getInstance().identify(mTemplate2);
                if(TextUtils.isEmpty(id)){
                    mStatusTextView.setText(getString(R.string.identify_fail));
                }else{
                    mStatusTextView.setText(""+getString(R.string.identify_success)+",id="+id);
                }
            }
        }
    }

    Bitmap tetet;
    Handler handler = new Handler(){
        @Override
        public void handleMessage(@NonNull Message msg) {
            switch (msg.what){
                case 0:
                    Bitmap newBitmap = rotateMyBitmap(tetet);
                    mFirstImage.setImageBitmap(newBitmap);
//                    byte[] temp = null;//ZKLiveFaceManager.getInstance().getTemplateFromBitmap(newBitmap);
//                    try {
//                        temp = ZKLiveFaceManager.getInstance().getTemplateFromBitmap(newBitmap);
//                        System.out.println("------==========");
//                    }catch (Exception e){
//
//                    }
//                    try {
//                        byte[] temp2 = ZKLiveFaceManager.getInstance().getTemplateFromBitmap(tetet);
//                        System.out.println("------==========");
//                    }catch (Exception e){
//
//                    }
//                    byte[] temp2 = ZKLiveFaceManager.getInstance().getTemplateFromBitmap(tetet);
//                    if(temp != null && temp[0] != 0){
//                        temp = temp2;
//                    }else{
//
//                    }
//                    mStatusTextView.setText("bitmap转换成功 byte.length " + temp == null ? " null" : "非 null");

//                    byte[] temp = changeBitmapToBytes(tetet);
//                    byte[] temp = ZKLiveFaceManager.getInstance().getTemplateFromBitmap(tetet);
//                    if(temp != null){
//
////                mTemplate2 = ZKLiveFaceManager.getInstance().getTemplateFromNV21(temp,CAMERA_WIDTH,CAMERA_HEIGH);
////                if(mTemplate2 == null){
////                    mStatusTextView.setText(getString(R.string.extract_template_fail));
////                    return;
////                }
//
//                        String id = ZKLiveFaceManager.getInstance().identify(temp);
//                        if(TextUtils.isEmpty(id)){
//                            mStatusTextView.setText(getString(R.string.identify_fail));
//                        }else{
//                            mStatusTextView.setText(""+getString(R.string.identify_success)+",id="+id);
//                        }
//                    }
                    break;
                case 1:

//                    String path = Environment.getExternalStorageDirectory().getPath() + "/124.jpg";
//                    Bitmap mSecondBitmap;
//                    mSecondBitmap = BitmapFactory.decodeFile(path);
//                    if(mSecondBitmap == null){
//                        return;
//                    }
//                    byte[] abdf = ZKLiveFaceManager.getInstance().getTemplateFromBitmap(mSecondBitmap);
//                    SecondTemplate
                    String id = ZKLiveFaceManager.getInstance().identify(SecondTemplate);
                    if(TextUtils.isEmpty(id)){
                        mStatusTextView.setText(getString(R.string.identify_fail));
                    }else{
                        mStatusTextView.setText(""+getString(R.string.identify_success)+",id="+id);
                    }
                    break;
            }

        }
    };

    public void onDestroy(){
        super.onDestroy();
        mTemplate1 = null;
        mTemplate2 = null;
    }


//    OrientationEventListener orientationListener = createOrientationListener();
//    private OrientationEventListener createOrientationListener() {
//        return new OrientationEventListener(IdentifyFromCamera.this) {
//            public void onOrientationChanged(int orientation) {
//                try {
//                    if (orientation != OrientationEventListener.ORIENTATION_UNKNOWN) {
//                        setCameraDisplayOrientation(getWindowManager().getDefaultDisplay().getRotation());
//                    }
//                } catch (Exception e) {
//                }
//            }
//        };
//    }
//
//    int currentSetRotation = -1;
//    public void setCameraDisplayOrientation(int displayRotation) {
//        int degrees = 0;
//        switch (displayRotation) {
//            case Surface.ROTATION_0: degrees = 0; break;
//            case Surface.ROTATION_90: degrees = 90; break;
//            case Surface.ROTATION_180: degrees = 180; break;
//            case Surface.ROTATION_270: degrees = 270; break;
//        }
//
//        int result;
//        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
//        if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
//            result = (cameraInfo.orientation + degrees) % 360;
//            result = (360 - result) % 360;  // compensate the mirror
//        } else {  // back-facing
//            result = (cameraInfo.orientation - degrees + 360) % 360;
//        }
//        if(result != currentSetRotation) {
//            currentSetRotation = result;
//            mCamera.setDisplayOrientation(result);
//        }
//    }

    /**
     * 旋转图片
     * @return 旋转后图片（只是修改了Bitmap对象，没有修改图片文件)
     */
    public Bitmap rotateMyBitmap(Bitmap bmp) {
        Matrix matrix = new Matrix();
        matrix.postRotate(90);
        Bitmap rotatedBitMap = Bitmap.createBitmap(bmp, 0, 0, bmp.getWidth(), bmp.getHeight(), matrix, true);
        return rotatedBitMap;
    }

    /**
     * bitmap转byte[]
     * @param photo
     */
    public byte[] changeBitmapToBytes(Bitmap photo){
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
//创建对应的流对象

        photo.compress(Bitmap.CompressFormat.JPEG,100,byteArrayOutputStream);//将流对象与Bitmap对象进行关联。

        byte [] xx=byteArrayOutputStream.toByteArray();//使用流对象，将Bitmap对象转换为byte[]数组
        return xx;
    }

    private void byFile(){
        String path = Environment.getExternalStorageDirectory().getPath() + "/124.jpg";
        Bitmap mSecondBitmap;
        mSecondBitmap = BitmapFactory.decodeFile(path);
        if(mSecondBitmap == null){
            return;
        }
        SecondTemplate = ZKLiveFaceManager.getInstance().getTemplateFromBitmap(mSecondBitmap);
//        String ttemp = "2E5626B00B8CEED142E0EE02D6D8EC53082C6240CE1152D77C2A377B8DF2E8240B6162F1AD54A29691540125A87EE0E33E9F4C404F8378EE7EE84FE566E17852656D7B54C393354B8F73CC75468BDBFDDD57C552905EF69496F46E0F765C980290DF33B250DE53DF1975EF07D6A8B5138AF70350F09956CD3F378B2444091134DC869C780DB4116636579493BD65A969DF6BB4A128E909C26FB68C07356D2E21F3238C1CA2AA2403899CACDF6E5D549C32C0743D8CD308A0C3BF5C38B2BCBC8C4AB9CF512B88CA6DC37F69ECAFCC6F482369EC22C34A127CA85FB110F1ED6ECE74E7AC1B27AECC29E416DC8A885852D2F59DD1D1BE8D871EEA631B8B4B478743087713B1B1FA3C3A5AD09C67BE5116A9779BDC07A9BBB04D51A59CE736C2498533087DF3119FCD4DD9F98328005E5353242B87FDA61D9E62DC87831B7EBEA8B758F0BB45906C2C6181B27231D7DDD649D5645AD8934C561D1BAD864C937DA1F335483CB4DDAEEB46A419A971B5F06D34A4A36E06742AA8EA210162A69E166BCEEFD0AE9BE112B67C9D6D0ED9946A7AB28C57855A85ADFADC55E0210E446BA05CE6ED990AEDDF0EBEB54E2B5C50F4600DF5C3B7D620A92E3AFCCF7266067E39D50A658AE386C2FC364249D75FDAC3AB1902284BFE3965D060C539A1CC93836458BBDD7BC03D9156D6D4706331E165AFE6F1D9BB1BBCA9D3BC49E53C5D8C29FB4ECDA0AA56A7B989F60C276BAD86E16B22DDBC65ED24E948B940DD2965488267F2FFA697C4841DDC8B03E38E4A55626174F4E66414240F5082AFB3318D9F5C5A714C80D12E799869CA9F9E3D12AFA4D7E6426646D547020D858D588F932410012DB3BA2FEC0469EC2BCD44FB4495932ABAACBA6F90EB28E3027A52D049BCEC53A467CCB1BD45576B47A46DD45EEA1B9886F105C8A70D6694EF8B38DE7766A8F1BEAD624579A6BC4713E9DA8EBC0573A123C4E3CC08E32634A49DC5644E237D265A5F3D4EBC37D0C5CA9D801FA7D963CF0114B02C9E050F45920C02A7C9F0B61E92FDD2C8374CB78FEF4208830F316F47E2A246653962B4BDAA6E4326685A6E2EE275E667CE3E39A712ABB7AAD36EE7F22DA1B81FC1B71E0FE727FEED3C3A966EBEE1560568E0D94165332141917C23AE6021291C89620E9E7C537FDF90DA846D299FD38A006FF3E6BDE283803444C16C7C47CDE1915EF3ECC87879AA781CF23DDBAD27B16366A886E98C3A313385FD1D54A042381847F31125B4590AE05E9633F20E07DC6D455DA18625975FF1C2EED8C8E6D1EF22DD981D4CB1F10A3AF9580D25492CF3AAF3E366D9E362D6A12C3E2692D61F441B963C08B4ACD321BF949B997863FC525860B4A425FD5233968A9EC3C509F953F79E5B7FFC2BEF2EC44BEE11AD7697D10A070387EA1DD436DAD3EF4F932763040744DD6A5D737BC7B64D01499E65E2DAB354EFB1E178B0631C5C73BB92D992C08034478CB58B8C23D7A1DEA9318CD6EEEAD626A44AC59AF21F6ED674840A06AFEBADA75CC3EEBFE44D5042BD7685FBC8440D12D736470B2F5AE3AFDA009B182CE5DDFDC91CAB0B21B560BBB3DEDB7147C614745C67B2D1EF58E5B0015453C2712880394379D103D9E2763ECA62E7FAFAC0AAFBC5BF4DFC62714539D09D99DE11FCE96086059DF3176C172799EBED59644568DEE10E8870E4A0FF70032E265188E671C04668A83C9B5604CF6C30447965ECC06A17700D6B8AF99349B9BB37F7FC7E12E0E3FBE09CE9EAA9038560806ED5652A94D3E7407809B41C57C0E6044C08BEE246AE1DAFEF86E0E30FC5A2BCB269D1D7E1BF8670E95FD1E206AD2EDB3F16B129076431EFCB52AFC1A225703DE5CFB1A97E97614D673FC0B75ABCCE30D9912506AEB51C152F5A19ED533455263C65F4D4226481D0114E2F414F5CB0FC63AB918092508985194494190EC6A77D5F8F70021F2A4DF733AB2447FE7F4235A0837F6F1D0970F25678CEB14033A616B095428CC32C31DBB3F946340346F2A71C203A451EC93912AEE862620813E3A30A9E58B21AFA5F1412922BA862177864AAED7950464EB1984C145750944CCCA939170B88FD9E2FF310872F4551AE6241522FBD4F48C331E4BADDD0E32A62FF99343222E9A22F056E4524D69686E79D3AC07CBB857B459F3B3C256413E5D0B814342A26EB9D2FFD1FE93AA1C7512F9B5FD89A652E86A74AA0ED794AF6C5F833CD16FB765A9C1203124E92FC0977DAA5F7A0991E0429A8919C63959D841862F0A6415BA729EB44508FAD53C403415BF4FF731271BEE39F8F8ACFA1A6C76AFB0D7CED77C4ABA9045B6D5C02C8157B2CA1AE1356815B5FF9B5E76947BB0C1BAC66FAC2061D89FADE11B2C0FAA4FDC8E5ADC3F804BE1507D437A7201EDA6825C6D27E67E0F9D6332E9C75A5085373242FDC5497F2EA18CFAD1F1AFC840793832CCF2B2675D03C7D77011B5696F2577C423E14C13EDED4B555070EFAAE365EED697C3D2004C7E371BE3CD706B1240BEFCEA8CA92AAA9CAB0BEE6DA6E88AF273363E362CD5979658875A636C9547C40915AF0DA8B419E53E4AD4293FFB0A24BDCA40309216D21DDBA6D15C87D942126C0FCF4DFDDB8ED5D72D4815F6B65F9A89F9569C1545D1A74DA47AC7FE233538927F1C07CE9D7E346708B61BF189EA5AF9EBF5B96C3FEF9A42476B92023697968F3565A8387BA6C52E6EB19DAC9F059460986F7CE354639CEFCB2C5CF26614DD391B317CA5D7C2CEFD705AD90C794975D10256B502469B052D24EEE8813B886A8C80637D3E6F05FEC6999460BDD49EE7877FB3D141538006A60571706B178569ED783A57678AAA2F310BDC352577FB1DD015A7907A427624A1CC5397F6F6F40FBF561";
//        SecondTemplate = StringUtils.hexToByte(ttemp);
//        String tttemp = StringUtils.bytesToHex(SecondTemplate,"");
//        Log.e("=========>>", "" + tttemp );
        if(ZKLiveFaceManager.getInstance().dbAdd(FileUtils.getFileName(path) + FACEID,SecondTemplate)){
            mStatusTextView.setText(""+getString(R.string.dbadd_template_success)+",id="+"faceID_"+FACEID);
            FACEID ++;
        }else{
            mStatusTextView.setText(getString(R.string.dbadd_template_fail));
        }


        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                handler.sendEmptyMessage(1);
            }
        },3000);

    }

    public Bitmap runInPreviewFrame(byte[] data, Camera camera) {
        ByteArrayOutputStream baos;
        byte[] rawImage;
//        camera.setOneShotPreviewCallback(null);
        //处理data
        Camera.Size previewSize = camera.getParameters().getPreviewSize();//获取尺寸,格式转换的时候要用到
        BitmapFactory.Options newOpts = new BitmapFactory.Options();
        newOpts.inJustDecodeBounds = true;
        YuvImage yuvimage = new YuvImage(
                data,
                ImageFormat.NV21,
                previewSize.width,
                previewSize.height,
                null);
        baos = new ByteArrayOutputStream();
        yuvimage.compressToJpeg(new Rect(0, 0, previewSize.width, previewSize.height), 100, baos);// 80--JPG图片的质量[0-100],100最高
        rawImage = baos.toByteArray();
        //将rawImage转换成bitmap
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inPreferredConfig = Bitmap.Config.RGB_565;
        return BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length, options);
    }
}
